from twisted.enterprise import adbapi
from datetime import datetime
import pymysql
from utils import *

import logging
_logger = logging.getLogger(__name__)


params = dict(
    host='localhost',
    user='root',
    password='123456',
    db='dcs',
    charset='utf8',  # 不能用utf-8
    cursorclass=pymysql.cursors.DictCursor
)
dbpool = adbapi.ConnectionPool("pymysql", **params)

factory_name = None  # 厂区名

# 保存 机台/纱锭 的上一次 状态值，
# 用于与 最新获得的状态值 比较，如果发生改变，则需要存入数据库中，
# previous_spindles_status = {"machine_ip": { "spindle_no": 3 } }
previous_spindles_status = {}


def is_changed(machine_ip, spindle_no, status):
    """ 检查 纱锭状态是否发生变化 """

    machine = previous_spindles_status.get(machine_ip, None)
    if not machine:
        previous_spindles_status[machine_ip] = {spindle_no: status}
        return True

    spindle = machine.get(spindle_no, None)
    if spindle is None or spindle != status:
        machine[spindle_no] = status
        return True

    return False


class Mysql(object):

    @classmethod
    def _save_data(self, txn, data):
        """ 每个纱锭每个时间点的状态，插入一条数据库表记录 """
        # TODO 将机器IP, 寄存器状态值，发生时间 存入 db
        _logger.debug("***** save_in_mysql *****")
        machine_ip = data.get('machine_ip', '')

        spindles_status = data.get('spindles_status', [])
        if (len(spindles_status) < 1):
            return

        dtime = datetime.now()
        sql_statement = "insert into spindle_status(spindle_no, status, machine_ip,  dtime) values "

        values = []
        for status in spindles_status:

            # 如果 纱锭状态发生变化， 才需要更新数据库状态
            if is_changed(machine_ip, status[0], status[1]):
                values.append("('%s',%d,'%s','%s')" % (status[0], status[1], machine_ip, dtime))

        # 没有发生变化，则无需做数据库操作
        if len(values) < 1:
            return

        sql_statement = sql_statement + ','.join(values)
        _logger.debug(sql_statement)

        txn.execute(sql_statement)

    @classmethod
    def save_in_mysql(self, data):
        """ 将数据存入 mysql """

        print_threading_info()
        try:
            # result = dbpool.runOperation("")
            result = dbpool.runInteraction(Mysql._save_data, data)
        except Exception as e:
            _logger.debug(e)

        result.addCallback(lambda x: print(x))


def read_configuration_from_mysql():
    """ 从 mysql 读取工厂基本信息，
        比如 厂区名、机台号与机台 ip地址的对应关系
        存放在全局变量中 或 存放在缓存
    """

    def get_info(results):
        global factory_name
        for config in results:
            factory_name = config.get('factory_name')

    result = dbpool.runQuery("select * from configuration limit 1")
    result.addCallback(get_info)


if not factory_name:
    read_configuration_from_mysql()


